<!DOCTYPE HTML>
<html>

<head>
	<link rel="bookmark"  type="image/x-icon"  href="/img/logo.png"/>
	<link rel="shortcut icon" href="/img/logo.png">
	
			    <title>
    Archer`s
    </title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <link rel="stylesheet" href="/css/mic_main.css" />
    <link rel="stylesheet" href="/css/dropdownMenu.css" />
    <meta name="keywords" content="Archer,arche2r,Arche2r,Archer的博客" />
    
    	<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
	 
    <noscript>
        <link rel="stylesheet" href="/css/noscript.css" />
    </noscript>
    <style type="text/css">
        body:before {
          content: ' ';
          position: fixed;
          top: 0;
          background: url('/img/bg.jpg') center 0 no-repeat;
          right: 0;
          bottom: 0;
          left: 0;
          background-size: cover; 
        }
    </style>

			    
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script async type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


    <script src="/js/jquery.min.js"></script>
    <script src="/js/jquery.scrollex.min.js"></script>
    <script src="/js/jquery.scrolly.min.js"></script>
    <script src="/js/skel.min.js"></script>
    <script src="/js/util.js"></script>
    <script src="/js/main.js"></script>
	
<meta name="generator" content="Hexo 4.2.0"></head>
    
		
<!-- Layouts -->



<!--  代码渲染  -->
<link rel="stylesheet" href="/css/prism_coy.css" />
<link rel="stylesheet" href="/css/typo.css" />
<!-- 文章页 -->
<body class="is-loading">
    <!-- Wrapper 外包 s-->
    <div id="wrapper" class="fade-in">
        <!-- Intro 头部显示 s -->
        <!-- Intro 头部显示 e -->
        <!-- Header 头部logo start -->
        <header id="header">
    <a href="/" class="logo">IT`S ME</a>
</header>
        <!-- Nav 导航条 start -->
        <nav id="nav" class="special" >
            <ul class="menu links" >
			<!-- Homepage  主页  --> 
			<li >
	            <a href="/" rel="nofollow">主页</a>
	        </li>
			<!-- categories_name  分类   --> 
	        
	        <!-- archives  归档   --> 
	        
	        <li class="active">
	            <a href="#s1">归档</a>
	                    <ul class="submenu">
	                        <li>
	                        <a class="archive-link" href="/archives/2022/01/">一月 2022</a></li><li><a class="archive-link" href="/archives/2020/06/">六月 2020</a></li><li><a class="archive-link" href="/archives/2019/08/">八月 2019</a></li><li><a class="archive-link" href="/archives/2019/06/">六月 2019</a></li><li><a class="archive-link" href="/archives/2019/05/">五月 2019</a>
	                    </ul>
	        </li>
	        
	        
		        <!-- Pages 自定义   -->
		        
		        <li>
		            <a href="/gallery/" title="图库">
		                图库
		            </a>
		        </li>
		        


            </ul>
            <!-- icons 图标   -->
			<ul class="icons">
                    
                    <li>
                        <a title="tv" href="https://space.bilibili.com/39520610" target="_blank" rel="noopener">
                            <i class="icon fa fa-tv"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="github" href="https://github.com/arche2r" target="_blank" rel="noopener">
                            <i class="icon fa fa-github"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="qq" href="tencent://message/?uin=1151147869&Site=&Menu=yes" target="_blank" rel="noopener">
                            <i class="icon fa fa-qq"></i>
                        </a>
                    </li>
                    
			</ul>
</nav>

        <div id="main" >
            <div class ="post_page_title_img" style="height: 25rem;background-image: url(/images/pic/90626/90626.jpg);background-position: center; background-repeat:no-repeat; background-size:cover;-moz-background-size:cover;overflow:hidden;" >
                <a href="#" style="padding: 4rem 4rem 2rem 4rem ;"><h2 >状态模式(内部状态模式)</h2></a>
            </div>
            <!-- Post -->
            <div class="typo" style="padding: 3rem;">
                <p><strong>允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类</strong></p>
<p>状态模式的定义告诉我们,它的动作会根据内部的状态而改变,我们用一个投票案例来进行说明:</p>
<p>主体类是创建的主要对象,它是投票的外壳</p>
<pre><code>/**
 * 容器外壳类,它是行为的主体
 * @author Archer    2019/6/26 20:26:53
 **/
public class Context {
//    内部维护一个state状态
    private State state;

    public Context(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }
//    投票由状态负责
    public void vote() {
        state.vote(this);
    }</code></pre><p>创建抽象状态类</p>
<pre><code>public abstract class State {
    //定义投票主体名字
    protected String name;
    //定义投票初始数量
    protected Integer count = 0;
    //初始化参数
    public State(String name, Integer count) {
        this.name = name;
        this.count = count;
    }
    //抽象方法让子类继承(来自context的行为)
    public abstract void vote(Context context);
}</code></pre><p>然后是三种不同的状态</p>
<pre><code>/**
 * 普通状态,投票数量小于5个
 * @author Archer    2019/6/26 20:29:45
 **/
public class StatenNormal extends State {
    public StatenNormal(String name, Integer count) {
        super(name, count);
    }

    @Override
    public void vote(Context context) {
        if (context.getState().count &lt; 5) {
            context.getState().count++;
            System.out.println(name + &quot;进行了一次投票&quot;);
        } else {
            StateLimit sl = new StateLimit(name, count);
            context.setState(sl);
            context.vote();
        }
    }
}

/**
 * 限制状态,投票数量大于5,小于8
 * @author Archer    2019/6/26 20:29:45
 **/
public class StateLimit extends State {
    public StateLimit(String name, Integer count) {
        super(name, count);
    }

    @Override
    public void vote(Context context) {
        if (context.getState().count &lt; 8) {
            context.getState().count++;
            System.out.println(name + &quot;,您的账号即将被限制投票(&quot; + count + &quot;/8)&quot;);
        } else {
            StateBan sb = new StateBan(name, count);
            context.setState(sb);
            context.vote();
        }
    }
}

/**
 * 禁止投票阶段,投票量大于8
 * @author Archer    2019/6/26 20:29:45
 **/
public class StateBan extends State {
    public StateBan(String name, Integer count) {
        super(name, count);
    }

    @Override
    public void vote(Context context) {
        System.out.println(name+&quot;,您的账号异常!&quot;);
    }
}</code></pre><p>测试类及结果</p>
<pre><code>@Test
public void testState() {
    Context context = new Context(new StatenNormal(&quot;张三&quot;, 0));
    context.vote();  //张三进行了一次投票
    context.vote();  //张三进行了一次投票
    context.vote();  //张三进行了一次投票
    context.vote();  //张三进行了一次投票
    context.vote();  //张三进行了一次投票
    context.vote();  //张三,您的账号即将被限制投票(6/8)
    context.vote();  //张三,您的账号即将被限制投票(7/8)
    context.vote();  //张三,您的账号即将被限制投票(8/8)
    context.vote();  //张三,您的账号异常!
    context.vote();  //张三,您的账号异常!
}</code></pre><p>状态模式和策略模式两者的UML建模图基本相似，区别在于↓<br><img src="/images/pic/90626/90626-1.png" alt="img"></p>
<p>状态模式的的思想是，状态之间的切换，在状态A执行完毕后自己控制状态指向状态B。状态模式是不停的切换状态执行。<br><img src="/images/pic/90626/90626-1.png" alt="img"><br>策略模式的思想上是，考虑多种不同的业务规则将不同的算法封装起来，便于调用者选择调用。策略模式只是条件选择执行一次。</p>
<p>策略和状态两者的UML图虽然相似,但实际上是两种完全不同的思想.策略重在算法的选择替换,主体对于所有的策略都有了解,可以根据不同的场景使用不同的策略,而状态模式重在自身的内部变化,将内在的动作委托到不同的类上,表现为类的变化.</p>

            </div>

            <!-- Post Comments -->
            

        </div>
        <!-- Copyright 版权 start -->
                <div id="copyright">
                <span id="busuanzi_container_site_pv"><span id="busuanzi_value_site_pv"></span>次的回眸</span>
<span>·</span>
				<span id="busuanzi_container_site_pv"> 2022 </span> 

        </div>
    </div>
</body>



 	
</html>
